package cn.xiaopengstack.domain.pay.service;

import cn.xiaopengstack.domain.order.model.valobj.AliPayResultMappingPayOrderStatusEnum;
import cn.xiaopengstack.domain.order.repository.IOrderRepository;
import cn.xiaopengstack.domain.pay.model.entity.CreatePayEntity;
import cn.xiaopengstack.domain.pay.model.entity.CreatePayReqEntity;
import cn.xiaopengstack.domain.pay.model.entity.PayResultEntity;
import cn.xiaopengstack.types.enums.PayChannelEnum;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author jiangyangang
 */
@Slf4j
@Service
public class AlipayService extends AbsPayService{

    @Value("${alipay.alipay_public_key}")
    private String alipayPublicKey;

    @Resource
    private AlipayClient alipayClient;

    @Value("${alipay.notify_url}")
    private String notifyUrl;
    @Value("${alipay.return_url}")
    private String returnUrl;


    public AlipayService(IOrderRepository orderRepository) {
        super(orderRepository);
    }

    @Override
    public CreatePayEntity createPay(CreatePayReqEntity reqEntity) throws AlipayApiException {
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(notifyUrl);
        request.setReturnUrl(returnUrl);

        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", reqEntity.getOrderId());
        bizContent.put("total_amount", reqEntity.getTotalAmount());
        bizContent.put("subject", reqEntity.getProductName());
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
        request.setBizContent(bizContent.toString());

        String form = alipayClient.pageExecute(request).getBody();

        return CreatePayEntity.builder()
                .payOrderId(RandomStringUtils.randomNumeric(11))
                .payChannel(reqEntity.getPayChannelEnum())
                .payUrl(form)
                .orderId(reqEntity.getOrderId())
                .userId(reqEntity.getUserId())
                .build();
    }

    @Override
    protected PayResultEntity analysisPayResult(Object payResult) throws Exception{
        HttpServletRequest request = (HttpServletRequest) payResult;
        log.info("支付宝支付回调，消息接收 {}", request.getParameter("trade_status"));

        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()) {
            params.put(name, request.getParameter(name));
        }

        aliResultBodySignCheck(params);

        // 验签通过
        LocalDateTime payTime = LocalDateTime.parse(params.get("gmt_payment"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String payChannelOrderId = params.get("trade_no");
        String orderId = params.get("out_trade_no");
        String aliPayResult = params.get("trade_status");
        AliPayResultMappingPayOrderStatusEnum statusEnum = AliPayResultMappingPayOrderStatusEnum.mappingResult(aliPayResult);
        return PayResultEntity.builder()
                .payTime(new Date(payTime.atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli()))
                .payChannelOrderId(payChannelOrderId)
                .orderId(orderId)
                .orderStatusEnumVO(statusEnum.getPayOrderStatusEnumVO())
                .build();
    }

    private void aliResultBodySignCheck(Map<String, String> params) throws AlipayApiException {
        String sign = params.get("sign");
        String content = AlipaySignature.getSignCheckContentV1(params);
        // 支付宝验签
        boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, alipayPublicKey, "UTF-8");
        if (!checkSignature) {
            throw new RuntimeException("支付宝验签失败!");
        }
    }

    /**
     * {
     *   "alipay_trade_query_response" : {
     *     "code" : "10000",
     *     "msg" : "Success",
     *     "buyer_logon_id" : "fnk***@sandbox.com",
     *     "buyer_pay_amount" : "0.00",
     *     "buyer_user_id" : "2088722076021591",
     *     "buyer_user_type" : "PRIVATE",
     *     "invoice_amount" : "0.00",
     *     "out_trade_no" : "15214856897329",
     *     "point_amount" : "0.00",
     *     "receipt_amount" : "0.00",
     *     "send_pay_date" : "2025-09-28 17:42:53",
     *     "total_amount" : "1.68",
     *     "trade_no" : "2025092822001421590506763341",
     *     "trade_status" : "TRADE_SUCCESS"
     *   },
     *   "sign" : "OzFS3vGtDHYV4kmMn9EzOWiZJ4q74CLpdR6tyJx122ydPYl6ddZjU5B9R7bn2DGpmJj88PbitsgU9boCWInaha0+y9VwcukGb7Z7w+rVvE0+hKcwq+iewvTNbGnp0XXybmM6sVU++H1qY8nrAs/OKbD21hYAA4TXba4njqr/YEdB+D3lzo/AOA4qPergoA0dBk0etM0s7UIlVPCRrzL8hCwsd1/mHfeOdIcxOCDSG9EDHbjRdvtQ2rQuvnCw7NPTmp1ruiDUgp4y2fdj8vgJfiB7Lp/rg+wBRvPYj7gbsqzNHhivTaDV7vk+t3cjLnyzfE6Wtbb/j12VBj4JMx8Vog=="
     * }
     * @param payOrderId
     * @return
     * @throws Exception
     */
    @Override
    public PayResultEntity queryPayResult(String payOrderId) throws Exception {
        // 执行查询
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        model.setTradeNo(payOrderId);
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        request.setBizModel(model);
        AlipayTradeQueryResponse queryResponse = alipayClient.execute(request);

        // 查询结果解析
        JSONObject paramsJson = JSONObject.parseObject(queryResponse.getBody());
        JSONObject queryParam = paramsJson.getJSONObject("alipay_trade_query_response");
        HashMap<String, String> params = new HashMap<>();
        for (Map.Entry<String, Object> entry : queryParam.entrySet()) {
            params.put(entry.getKey(), entry.getValue().toString());
        }
        params.put("sign", paramsJson.getString("sign"));

        // 验签
        aliResultBodySignCheck(params);

        // 参数组装
        LocalDateTime payTime = LocalDateTime.parse(params.get("send_pay_date"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String payChannelOrderId = params.get("trade_no");
        String orderId = params.get("out_trade_no");
        String aliPayResult = params.get("trade_status");
        AliPayResultMappingPayOrderStatusEnum statusEnum = AliPayResultMappingPayOrderStatusEnum.mappingResult(aliPayResult);
        return PayResultEntity.builder()
                .payTime(new Date(payTime.atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli()))
                .payChannelOrderId(payChannelOrderId)
                .orderId(orderId)
                .orderStatusEnumVO(statusEnum.getPayOrderStatusEnumVO())
                .build();
    }

    @Override
    public PayChannelEnum channel() {
        return PayChannelEnum.ali_pay;
    }

    public static void main(String[] args) {
        LocalDateTime parse = LocalDateTime.parse("2025-09-28 17:11:35", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println(parse.atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli());
    }
}
